﻿/*
 * @author: wizardc
 */

using System;
using System.Collections;
using System.IO;
using Dou.Utils;
using UnityEngine;
using UnityEngine.Networking;

namespace Dou.Resource
{
    /// <summary>
    /// 资源工具类
    /// </summary>
    public static class AssetUtil
    {
        
#if UNITY_EDITOR
        /// <summary>
        /// 热更资源的存放目录
        /// </summary>
        public static readonly string HotFixedDir = "./hotfixed";
#else
        /// <summary>
        /// 所有游戏打包资源的存放目录
        /// </summary>
        public static readonly string HotFixedDir = Application.persistentDataPath + "/hotfixed/";
#endif
        
        /// <summary>
        /// 包内资源的存放目录
        /// </summary>
        public static readonly string InPackageDir = Application.streamingAssetsPath;

        /// <summary>
        /// 包内文件路径协议头
        /// </summary>
        public const string InPackageProtocol = "file://";
        
        /// <summary>
        /// 包内文件路径协议头 Android 平台
        /// </summary>
        public const string InPackageProtocolJar = "jar:file://";
        
        /// <summary>
        /// 获取文件的完整路径
        /// 优先查找 PersistentDataPath 路径再查找 StreamingAssetPath 路径
        /// </summary>
        public static string GetFilePath(string filePath)
        {
#if UNITY_EDITOR
            var hotFixedPath = GetFilePathInHotFix(filePath);
            if (File.Exists(hotFixedPath))
            {
                return hotFixedPath;
            }
#else
            var hotFixedManifest = HotFixedManager.instance.hotFixedManifest;
            if (hotFixedManifest != null && hotFixedManifest.fileInfoMap.ContainsKey(filePath))
            {
                return GetFilePathInHotFix(filePath);
            }
#endif
            return GetFilePathInPackage(filePath);
        }

        /// <summary>
        /// 获取热歌文件夹内的文件路径
        /// </summary>
        public static string GetFilePathInHotFix(string filePath)
        {
            return Path.Combine(HotFixedDir, filePath);
        }
        
        /// <summary>
        /// 获取包内文件路径
        /// </summary>
        public static string GetFilePathInPackage(string filePath)
        {
            return Path.Combine(InPackageDir, filePath);
        }

        /// <summary>
        /// 判定指定文件是否是包内文件
        /// 包内文件不能使用 File 直接读取，需要使用 UnityWebRequest 协议的形式加载
        /// </summary>
        public static bool IsInPackageFile(string fullPath)
        {
            return fullPath.StartsWith(InPackageProtocol) || fullPath.StartsWith(InPackageProtocolJar);
        }

        /// <summary>
        /// 读取二进制文件，该方法同时支持读取包内（streamingAssetsPath）和外部的文件
        /// </summary>
        public static void ReadFile(string path, Action<byte[]> onComplete, Action onError = null)
        {
            var inPackage = IsInPackageFile(path);
            if (inPackage)
            {
                CoroutineUtil.StartCoroutine(RequestFile(path, onComplete, onError));
            }
            else
            {
                if (File.Exists(path))
                {
                    var bytes = File.ReadAllBytes(path);
                    onComplete?.Invoke(bytes);
                }
                else
                {
                    onError?.Invoke();
                }
            }
        }
        
        private static IEnumerator RequestFile(string uri, Action<byte[]> onComplete, Action onError)
        {
            var request = UnityWebRequest.Get(uri);
            yield return request.SendWebRequest();
            if (request.result != UnityWebRequest.Result.Success)
            {
                onError?.Invoke();
            }
            else
            {
                onComplete?.Invoke(request.downloadHandler.data);
            }
        }
    }
}
